﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using Kugar.Core.ExtMethod;
using Kugar.UI.Web.AdminLTE.Helpers;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Newtonsoft.Json;

namespace Kugar.UI.Web.AdminLTE.PageControls.PageCommon
{
    public class PageCommon_Tree : ControlBase
    {
        private int _maxLevel = 4;
        private IEnumerable<SelectorItem> _rootNodes = null;
        private Func<SelectorItem,string> _onItemClickFunc=null;
        private string _onChangedCallback="";
        private Func<SelectorItem, IEnumerable<SelectorItem>> _childFunc = null;
        //private bool _accordion = false;
        private bool _toggleNodeOnClick = true;
        private bool _isMultiSelect=false;
        private string _name="";
        private string[] _selectedValues=Array.Empty<string>();

        public PageCommon_Tree(ViewContext viewContext) : base(viewContext)
        {
            this.Css("webui_treeview ");
        }

        /// <summary>
        /// 最大输出的层级,默认为4级,-1为不限制
        /// </summary>
        /// <param name="level"></param>
        /// <returns></returns>
        public PageCommon_Tree MaxLevel(int level)
        {
            _maxLevel = level;

            return this;
        }

        /// <summary>
        ///  顶级根节点列表
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public PageCommon_Tree Root(IEnumerable<SelectorItem> source)
        {
            _rootNodes = source;
            return this;
        }

        public PageCommon_Tree Root(IEnumerable<(string title,string value)> source)
        {
            _rootNodes = source.Select(x=>new SelectorItem(x.title,x.value,false));
            return this;
        }


        public PageCommon_Tree Root(SelectorItem source)
        {
            _rootNodes = new[] { source };
            return this;
        }

        public PageCommon_Tree Root((string title,string value) source)
        {
            var item=new SelectorItem(source.title,source.value);

            _rootNodes = new[] { item };
            return this;
        }

        /// <summary>
        /// 用于获取下级数据源的函数
        /// </summary>
        /// <param name="childrenFunc"></param>
        /// <returns></returns>
        public PageCommon_Tree Children(Func<SelectorItem, IEnumerable<SelectorItem>> childrenFunc)
        {
            _childFunc = childrenFunc;

            return this;
        }

        public PageCommon_Tree Children(Func<SelectorItem, IEnumerable<(string title,string value)>> childrenFunc)
        {
            _childFunc =(item)=>
            {
                var arr = childrenFunc(item);

                if (!arr.HasData())
                {
                    return Array.Empty<SelectorItem>();
                }

                return arr.Select(x => new SelectorItem(x.title, x.value));
            };

            return this;
        }


        public PageCommon_Tree OnItemClickCallback(Func<SelectorItem,string> onClickScript)
        {
            _onItemClickFunc = onClickScript;
            return this;
        }

        public PageCommon_Tree OnItemClickCallback(string onClickScript)
        {
            _onItemClickFunc = (x)=>onClickScript;
            return this;
        }

        /// <summary>
        /// 树形控件的Name,,用于form中
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public PageCommon_Tree Name(string name){
            _name=name;

            return this;
        }

        /// <summary>
        /// 需要选中的项的Value值,区分大小写
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public PageCommon_Tree SelectedValues(IEnumerable<string> values)
        {
            _selectedValues=values.ToArrayEx();

            return this;
        }

        /// <summary>
        /// 选中的节点Value值(单个)
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public PageCommon_Tree SelectedValues(string values)
        {
            _selectedValues = new[] {values};

            return this;
        }

        public PageCommon_Tree OnChangedScript(string onChangedChanged){
            _onChangedCallback=onChangedChanged;

            return this;
        }

        public PageCommon_Tree ToggleNodeOnClick(bool toggle = true)
        {
            _toggleNodeOnClick = toggle;
            return this;
        }

        public PageCommon_Tree MultiSelect(bool isMultiSelect=true){
            _isMultiSelect=isMultiSelect;

            return this;
        }

        public override HtmlString Render()
        {
            this//.Data("accordion", _accordion.ToStringEx())
                .Data("togglenodeonclick", _toggleNodeOnClick.ToStringEx())
                .Data("changedcallback",_onChangedCallback)
                .Data("mutilselect",_isMultiSelect.ToStringEx())
                ;

            var rootNodes = _rootNodes.ToArrayEx();

            if (_withOuterBorder)
            {
                ViewContext.Writer.WriteLine($"<div class=\"{_outerBorderCss}\">");
            }

            ViewContext.Writer.WriteLine($"<div {Attributes}>");

            ViewContext.Writer.WriteLine($"<div class=\"treeview_tree_wrapper\">");
            
            var level = _maxLevel;
            
            if (rootNodes.HasData())
            {
                ViewContext.Writer.WriteLine($"<ul class=\"treeview_treeul\">");

                foreach (var firstLevel in rootNodes)
                {
                    renderMenuItem(firstLevel, ref level);
                }

                ViewContext.Writer.WriteLine("</ul> <!-- .treeview_treeul -->");
            }
            else
            {
                ViewContext.Writer.WriteLine("<div class=\"nondata\">暂无数据</div>");
            }
            
            ViewContext.Writer.WriteLine("</div> <!-- .treeview_tree_wrapper -->");

             if(!string.IsNullOrEmpty(_name) ){
                var currentValue=_selectedValues.HasData()?_selectedValues.JoinToString(','):"";
                ViewContext.Writer.WriteLine($"<input type=\"hidden\" name=\"{_name}\" value=\"{currentValue}\" />");
            }           

            ViewContext.Writer.WriteLine("</div>");

            if (_withOuterBorder)
            {
                ViewContext.Writer.WriteLine($"</div> <!-- outer border -->");
            }

            return HtmlString.Empty;
        }

        private void renderMenuItem(SelectorItem menuItemData, ref int level)
        {
            //level += 1;
            

            var isSelected=_selectedValues?.Contains(menuItemData.Value)==true;

            //ViewContext.Writer.WriteLine($"<li data-level=\"{level}\"  data-value=\"{menuItemData.Value}\"  data-onclick=\"{_onItemClickFunc?.Invoke(menuItemData)}\"> <a class=\"{(isSelected?"jstree-clicked":"")}\"><span class=\"jstree-title\">{menuItemData.Title}</span></a>");

            //ViewContext.Writer.WriteLine($"<li data-jstree='{{\"disabled:\"{(menuItemData.Disabled ? "true" : "false")},\"selected\":{(isSelected?"true":"false")}}}' data-level=\"{level}\"  data-value=\"{menuItemData.Value}\"  data-onclick=\"{_onItemClickFunc?.Invoke(menuItemData)}\">{menuItemData.Title}");

            ViewContext.Writer.WriteLine($"<li data-jstree='{{\"selected\":{(isSelected?"true":"false")}}}' data-level=\"{level}\"  data-value=\"{menuItemData.Value}\"  data-onclick=\"{_onItemClickFunc?.Invoke(menuItemData)}\">{menuItemData.Title}");


            if (_maxLevel != -1 && level - 1 < 0)
            {
                return;
            }

            var children = _childFunc?.Invoke(menuItemData);

            if (children.HasData())
            {
                level -= 1;

                ViewContext.Writer.WriteLine("<ul>");

                foreach (var child in children)
                {
                    renderMenuItem(child, ref level);
                }

                ViewContext.Writer.WriteLine("</ul> ");

                level += 1;
            }

            ViewContext.Writer.WriteLine("</li>");
        }
    }
}
